package com.youlu.campus.service.ca.impl;

import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.CaCertificateConfig;
import com.youlu.campus.entity.CaTemplate;
import com.youlu.campus.entity.CertificateActivityConfig;
import com.youlu.campus.entity.VO.req.CopyCaCertificateConfigReq;
import com.youlu.campus.entity.VO.req.CreateCaCertificateConfigVO;
import com.youlu.campus.entity.VO.req.QueryCertActivityConfigReq;
import com.youlu.campus.entity.VO.res.UserCaHonorRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CaCertificateConfigService {

    @Autowired
    private MongoTemplate mongoTemplate;

    public List<UserCaHonorRes> findByActivityId(String  activityId){
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.with(Sort.by(Sort.Direction.ASC, "createdTime"));
        List<CaCertificateConfig> list = this.mongoTemplate.find(query, CaCertificateConfig.class);
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
       return list.stream().map(caCertificateConfig -> {
            UserCaHonorRes userCaHonorRes = new UserCaHonorRes();
            userCaHonorRes.setCaType(caCertificateConfig.getCaType());
            userCaHonorRes.setCaLevel(caCertificateConfig.getCaLevelName());
            userCaHonorRes.setCertificateName(caCertificateConfig.getCertificateName());
           userCaHonorRes.setCertificateActivityConfigId(caCertificateConfig.getId());
            CaTemplate caTemplate = this.mongoTemplate.findById(caCertificateConfig.getTemplateId(), CaTemplate.class);
            if(Objects.nonNull(caTemplate)){
                userCaHonorRes.setBackgroundPic(caTemplate.getBackgroundPic());
            }
            return userCaHonorRes;
        }).collect(Collectors.toList());
    }


    public void saveOrUpdate(CreateCaCertificateConfigVO createCaCertificateConfig){
        String id = createCaCertificateConfig.getId();
        CaCertificateConfig caCertificateConfig = null;
        if(StringUtils.isEmpty(id)){
            caCertificateConfig = new CaCertificateConfig();
            caCertificateConfig.setCreatedTime(new Date());
        }else{
            caCertificateConfig = mongoTemplate.findById(id, CaCertificateConfig.class);
            caCertificateConfig.setUpdatedTime(new Date());
        }
        BeanUtils.copyProperties(createCaCertificateConfig,caCertificateConfig);
        mongoTemplate.save(caCertificateConfig);
    }

  public CaCertificateConfig detail(String id){
      CaCertificateConfig caCert = this.mongoTemplate.findById(id, CaCertificateConfig.class);
      String activityId = caCert.getActivityId();
      Query query = new Query();
      query.addCriteria(Criteria.where("id").is(caCert.getCertificateId()));
      query.addCriteria(Criteria.where("activityId").is(activityId));
      CertificateActivityConfig certActivity = this.mongoTemplate.findOne(query, CertificateActivityConfig.class);
      if(Objects.nonNull(certActivity)){
          caCert.setCaActivityLevel(certActivity.getCaActivityLevel());
      }
      ActivityInfo activityInfo = this.mongoTemplate.findById(activityId, ActivityInfo.class);
      if(Objects.nonNull(activityInfo)){
          caCert.setActivityName(activityInfo.getName());
      }
      return caCert;
  }

  public Page<CaCertificateConfig> list(QueryCertActivityConfigReq queryCertActivityConfigReq){
      Integer pageSize = queryCertActivityConfigReq.getPageSize();
      Integer page = queryCertActivityConfigReq.getPage();
      String activityId = queryCertActivityConfigReq.getActivityId();
      PageRequest pageRequest = PageRequest.of(page - 1, pageSize);
      Query query = new Query();
      if(StringUtils.isNotBlank(activityId)){
          query.addCriteria(Criteria.where("activityId").is(activityId));
      }
      long count = this.mongoTemplate.count(query, CaCertificateConfig.class);
      if(count==0){
          return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
      }
//      query.with(new Sort(Sort.Direction.DESC, "createdTime"));
      Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
      query.with(sort);
      List<CaCertificateConfig> list = this.mongoTemplate.find(query.with(pageRequest), CaCertificateConfig.class);
      list.stream().forEach(caCertificateConfig -> {
          ActivityInfo activityInfo = this.mongoTemplate.findById(caCertificateConfig.getActivityId(), ActivityInfo.class);
          if(Objects.nonNull(activityInfo)){
              caCertificateConfig.setActivityName(activityInfo.getName());
          }

      });
      return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
  }

    /**
     * 活动ID、证书类型、证书等级获取电子证书配置信息
     * @param activityId
     * @param cayType
     * @param caLevel
     * @return
     */
   public CaCertificateConfig findByActivityIdAndCaTypeAndCaLevel(String activityId,String cayType,String caLevel){
       log.info("ca certificate config param-> activityId ->{} cayType->{} caLevel->{}",activityId,cayType,caLevel);
       if(StringUtils.isBlank(activityId)||StringUtils.isBlank(caLevel)||StringUtils.isBlank(cayType)){
           throw new BusinessException("获取电子证书配置参数错误");
       }
       Query query = new Query();
       query.addCriteria(Criteria.where("activityId").is(activityId));
       query.addCriteria(Criteria.where("caType").is(cayType));
       if(StringUtils.isNotBlank(caLevel)){
           query.addCriteria(Criteria.where("caLevelName").is(caLevel));
       }
       CaCertificateConfig caCertificateConfig = this.mongoTemplate.findOne(query, CaCertificateConfig.class);
       if(Objects.isNull(caCertificateConfig)){
           throw new BusinessException("电子证书配置信息不存在");
       }
       return caCertificateConfig;
   }

   public List<CaCertificateConfig> findByActivityIdAndCaType(String activityId,String cayType){
       log.info("ca certificate config param-> activityId ->{} cayType->{}",activityId,cayType);
       if(StringUtils.isBlank(activityId)||StringUtils.isBlank(cayType)){
           throw new BusinessException("获取电子证书配置参数错误");
       }
       Query query = new Query();
       query.addCriteria(Criteria.where("activityId").is(activityId));
       query.addCriteria(Criteria.where("caType").is(cayType));
       List<CaCertificateConfig> caCertificateConfigList = this.mongoTemplate.find(query, CaCertificateConfig.class);
       if(CollectionUtils.isEmpty(caCertificateConfigList)){
           throw new BusinessException("电子证书配置信息不存在");
       }
       return caCertificateConfigList;
    }

    @Async
    public void copyCaCertificateConfig(CopyCaCertificateConfigReq copyCaCertificateConfigReq){
        String copyActivityId = copyCaCertificateConfigReq.getCopyActivityId();
        String copySourceCertificateId = copyCaCertificateConfigReq.getCopySourceCertificateId();
        log.info("【copy 活动电子证书配置】开始复制活动证书电子证书配置 sourceActivityId->{} | certificateId->{}",copyActivityId, copySourceCertificateId);
        Query query = new Query();
        query.addCriteria(Criteria.where("certificateId").is(copySourceCertificateId));
        query.addCriteria(Criteria.where("activityId").is(copyActivityId));
        List<CaCertificateConfig> caCertificateConfigList = this.mongoTemplate.find(query, CaCertificateConfig.class);
        if(CollectionUtils.isEmpty(caCertificateConfigList)){
            log.error("【copy 活动电子证书配置】结束复制活动证书电子证书配置 未查询到 sourceActivityId->{} | certificateId->{}",copyActivityId,
                    copySourceCertificateId);
            return;
        }
        Date now = new Date();
        List<CaCertificateConfig> targetCaCertificateConfigList = caCertificateConfigList.stream().peek(caCertificateConfig -> {
            caCertificateConfig.setId(null);
            caCertificateConfig.setActivityId(copyCaCertificateConfigReq.getTargetCopyActivityId());
            caCertificateConfig.setCertificateId(copyCaCertificateConfigReq.getCopyTargetCertificateId());
            caCertificateConfig.setCreatedTime(now);
            caCertificateConfig.setUpdatedTime(now);
        }).collect(Collectors.toList());
        this.mongoTemplate.insertAll(targetCaCertificateConfigList);
        log.info("【copy 活动电子证书配置】结束复制活动证书电子证书配置 sourceActivityId->{} | certificateId->{}",copyActivityId, copySourceCertificateId);
    }


}
